#!/usr/bin/env python
""" AnyBackup is a windows specific backup program to keep multiple volumes in sync with multiple volumes
    Copyright (C) 2014  Andrew Hopkinson

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    """
    
from backupManager import backupManager
import cPickle
import getopt
import sys
import re

BACKUP=2
CONTENT=3
ALL=4

backup = None

def store(self):
        if backup:
            with open('info.dat', 'wb') as f:
                try:
                    cPickle.dump(backup, f)
                except:
                    return False
            return True
        return False

try:
    with open('info.dat', 'rb') as f:
        backup = cPickle.load(f)
except:
    print "Error loading from info.dat"
if self.buManager is None:
    backup = backupManager()
    print "New backup instance created!"
    self.store()
if backup.readConfigs() == backupManager.INVALIDCONFIG:
    print "Invalid config options! Check your AnyBackup.cfg file."
   
     

def listDrives(remove = False):
    space = "                  "
    count = -1
    driveRef = {}
    backupDrives = backup.getBackupDrives()
    contentDrives = backup.getContentDrives()
    print '\nBackup Drives:'
    print '\tNumber'+space[6:]+"Name"+space[4:]+"Serial"+space[6:]+"Free/Total"
    print '\t----------------------------------------------------------------'
    for drive in backupDrives:
        count += 1
        free = "%.2f" % (drive.getFreeSpace()/float(1048576))
        total = "%.2f" % (drive.getTotalSpace()/float(1048576))
        print '\t'+str(count)+'.)'+space[len(str(count)+'.)'):]+drive.getName()+space[len(drive.getName()):]+drive.getSerial()+space[len(drive.getSerial()):]+str(free)+"/"+str(total)+"GB"
        driveRef[count]=drive
    print '\nContent Drives:'
    print '\tNumber'+space[6:]+"Name"+space[4:]+"Serial"+space[6:]+"Free/Total"
    print '\t----------------------------------------------------------------'
    for drive in contentDrives:
        count += 1
        free = "%.2f" % (drive.getFreeSpace()/float(1048576))
        total = "%.2f" % (drive.getTotalSpace()/float(1048576))
        print '\t'+str(count)+'.)'+space[len(str(count)+'.)'):]+drive.getName()+space[len(drive.getName()):]+drive.getSerial()+space[len(drive.getSerial()):]+str(free)+"/"+str(total)+"GB"
        driveRef[count]=drive
    print '\n'
    if remove and count:
        sys.stdout.write("Enter drive to remove [0-"+str(count)+"]> ")
        input = sys.stdin.readline()
        selection = re.findall('\d*',input,re.IGNORECASE)
        selection = selection[0]
        if selection > 0 and select <= count:
            return backup.removeDrive(driveRef[selection])
    return False

def importExtList(list):
    try:
        f = open(list,'r')
    except:
        print "Can't open " + list
        return False
    ext = []
    for line in f:
        line = re.sub('\n','',line)
        if line == '' or line is None:
            continue
        ext.append(line)
    backup.setValidExt(ext)
    store()
    return True

def importSkipList(list):
    try:
        f = open(list,'r')
    except:
        print "Can't open " + list
        return False
    skip = []
    for line in f:
        line = re.sub('\n','',line)
        if line == '' or line is None:
            continue
        skip.append(line)
    backup.setSkipList(skip)
    store()
    return True

def addSkip(skip):
    if skip is None:
        print "Must pass a string!"
        return False
    return backup.addSkip(skip)

def printSkipList():
    skipList = backup.getSkipList()
    if skipList:
        for skip in skipList:
            print skip
            
def addExt(ext):
    if ext is None:
        print "Must pass a string!"
        return False
    return backup.addValidExt(ext)
    
def printExtList():
    validExt = backup.getValidExt()
    if validExt:
        for ext in validExt:
            print ext

def displayMenu():
    while True:
        sys.stdout.write("> ")
        input = sys.stdin.readline()
        parseInput(input)
        
def help():
    print "Andrew's Backup Manager Help"
    print "----------------------------------------"
    print "refreshDrives [<backup/content>] - Refreshes files on all connected drives."
    print "addBackupDrive <drive letter> - Adds drive as a backup volume."
    print "addContentDrive <drive letter> - Adds drive as a content volume."
    print "removeDrive - Prints a list of drives to choose from for removal."
    print "oldFiles [drive:/path/to/file.txt] - Prints a report of files that appear in the backup volumes but not content volumes, optionally you can provide a file to print out to."
    print "toBackup [drive:/path/to/file.txt] - Prints a report of files that appear in the content volumes but not backup volumes, optionally you can provide a file to print out to."
    print "backup - backs up new files to the best estimate backup drive or to the drive which has the most free space."
    print "listDrives - Prints a list of backup and content volumes."
    print "regex - Searches backup volumes for files using the regex provided."
    print "importSkipList <drive:/path/to/file.txt] - imports a list of regular expressions to skip when looking for new files on the content drives, importing overwrites skips, it does not add to them."
    print "importExtList <drive:/path/to/file.txt] - imports a list of file extensions to load when looking for files on drives, importing overwrites all extensions, it does not add to them."
    print "addExt <file extension> (ex: addExt txt) - Adds a given extension to the list of file extensions looked for when indexing a drive."
    print "validExt - Prints out all valid file extensions."
    print "skipList - prints the current skip list."
    print "help - Prints this help menu."
    print "quit - exits script."
    
def parseInput():
    try:
        opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output="])
    except getopt.GetoptError, err:
        # print help information and exit:
        print str(err) # will print something like "option -a not recognized"
        help()
        sys.exit(2)

    if re.match("^quit$",input,re.IGNORECASE):
        store()
        print "Info saved."
        print "Goodbye. :)"
        sys.exit(0)
    elif re.match("^addBackupDrive\s+.+",input,re.IGNORECASE):
        match = re.findall("^addBackupDrive\s+(.+)",input,re.IGNORECASE)
        match = match[0]
        letters = match.split(',')
        for letter in letters:
            letter = re.sub('\s','',letter)
            if backup.addBackupDrive(letter):
                print "Backup drive " + letter + ": added."
            else:
                print "Error adding drive " + letter
    elif re.match("^addContentDrive\s+.+",input,re.IGNORECASE):
        match = re.findall("^addContentDrive\s+(.+)",input,re.IGNORECASE)
        match = match[0]
        letters = match.split(',')
        for letter in letters:
            letter = re.sub('\s','',letter)
            if backup.addContentDrive(letter):
                print "Content drive " + letter + ": added."
            else:
                print "Error adding drive " + letter
    elif re.match("^removeDrive$",input,re.IGNORECASE):
        if listDrives(True):
            print "Drive removed."
        else:
            print "Error removing drive!"
    elif re.match("^oldFiles$",input,re.IGNORECASE):
        files = backup.getOldFiles()
        print "Old files:"
        for file in files:
            print '\t' + file.getDir() + '/' + file.getName()
        print ''
    elif re.match("^toBackup$",input,re.IGNORECASE):
        files = backup.getNewFiles()
        print "Files to backup:"
        for file in files:
            print '\t' + file.getDir() + '/' + file.getName()
        print ''
    elif re.match('^importSkipList',input,re.IGNORECASE):
        file = re.findall("^importSkipList\s+(.+)",input,re.IGNORECASE)
        if not file:
            print "Must provide skip list to import, type help for more information about this and other commands."
            return
        file = file[0]
        if importSkipList(file):
            print "Skip list at " + file + " imported."
        else:
            print "Error importing skip list " + file
    elif re.match('^importExtList',input,re.IGNORECASE):
        file = re.findall("^importExtList\s+(.+)",input,re.IGNORECASE)
        if not file:
            print "Must provide ext list to import, type help for more information about this and other commands."
            return
        file = file[0]
        if importExtList(file):
            print "Ext list at " + file + " imported."
        else:
            print "Error importing ext list " + file
    elif re.match("^skiplist$",input,re.IGNORECASE):
        printSkipList()
    elif re.match("^validext$",input,re.IGNORECASE):
        printExtList()
    elif re.match("^addExt",input,re.IGNORECASE):
        ext = re.findall("^addExt\s+(.+)",input,re.IGNORECASE)
        if not ext:
            return
        ext = ext[0]
        if backup.addValidExt(ext):
            print ext + ' added'
        else:
            print "Error adding " + ext
    elif re.match("^addSkip",input,re.IGNORECASE):
        skip = re.findall("^addSkip\s+(.+)",input,re.IGNORECASE)
        if not skip:
            return
        skip = skip[0]
        if backup.addSkip(skip):
            print skip + ' added'
        else:
            print "Error adding " + skip
    elif re.match("^refreshDrives",input,re.IGNORECASE):
        type = re.findall("^refreshDrives\s+(.+)",input,re.IGNORECASE)
        if type:
            type = type[0]
            if re.match("content",type,re.IGNORECASE):
                backup.refreshDrives(backupManager.backupManager.CONTENT)
            if re.match("backup",type,re.IGNORECASE):
                backup.refreshDrives(backupManager.backupManager.BACKUP)
        else:
            backup.refreshDrives(backupManager.backupManager.ALL)
    elif re.match("^regex",input,re.IGNORECASE):
        regex = re.findall("^regex\s+(.*)",input,re.IGNORECASE)
        if not regex:
            return
        regex = regex[0]
        results = backup.searchFiles(regex)
        print "The following files match " + regex + ":"
        for result in results:
            print '\t' + result.getDir() + '/' + result.getName()
        print '\n'
    elif re.match("^help",input,re.IGNORECASE):
        help()
    elif re.match("^backup$",input,re.IGNORECASE):
        backup.backupNewFiles()
    elif re.match("^listdrives$",input,re.IGNORECASE):
        listDrives()
    else:
        print "Input not recognized, type help for a list of commands."
        
displayMenu()
            